package com.gitee.huanminabc.utils_common.base;

import com.gitee.huanminabc.jcommon.reflect.AnnotationUtil;
import com.gitee.huanminabc.jcommon.str.StringUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.apache.commons.lang3.reflect.FieldUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @program: monorepo
 * @description: 协议表格生成器
 * @author: huanmin
 * @create: 2025-01-22 15:36
 **/
public class GenContractHtmlUtil {
    //参数类型枚举 ,表格类型 ,值类型
    public enum ParamTypeEnum {
        TABLE, VALUE
    }

    @Data
    @AllArgsConstructor
    public static class ContractParam {
        //参数类型
        private ParamTypeEnum type;
        //参数名称
        private String name;
        //参数值
        private Object value;

        private Object defaultValue;
    }

    //创建ContractParam
    public static <T> ContractParam createContractParam(ParamTypeEnum type, String name, T value) {
        return new ContractParam(type, name, value, null);
    }

    //创建ContractParam
    public static <T> ContractParam createContractParam(ParamTypeEnum type, String name, T value, T defaultValue) {
        return new ContractParam(type, name, value, defaultValue);
    }

    /**
     * 生成协议html
     *
     * @param template       模板
     * @param prefix         前缀占位符
     * @param suffix         后缀占位符
     * @param contractParams 参数
     * @param structure      是否结构化- 就是有没有html外层的结构<html><head><body></body></head></html>
     * @param styleAll       样式 必须structure为true时才生效
     * @return
     */
    public static String genContractHtml(String template,
                                         String prefix,
                                         String suffix,
                                         Map<String, ContractParam> contractParams,
                                         boolean structure,
                                         String styleAll) {
        if (StringUtil.isAnyEmpty(template, prefix, suffix)){
            throw new RuntimeException("参数不合法");
        }

        template = switchReplaceParams(template, prefix, suffix, new ArrayList<>(contractParams.values()));
        if (!structure) {
            return template;
        }
        return createHtmlStructure(styleAll, template);

    }

    //html结构
    public static String createHtmlStructure(String styleAll, String template) {
        return "<!DOCTYPE html>\n" +
                "<html lang=\"zh\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>协议</title>\n" +
                "    <style> \n" + styleAll + "\n</style>\n" +
                "</head>\n" +
                "<body> \n" + template + "\n</body>\n" +
                "</html>";
    }


    private static String switchReplaceParams(String template, String prefix, String suffix, List<ContractParam> contractParams) {
        for (ContractParam contractParam : contractParams) {
            switch (contractParam.type) {
                case VALUE:
                    if (contractParam.value == null && contractParam.defaultValue != null) {
                        //替换模板中的值
                        template = template.replace(prefix + contractParam.name + suffix, contractParam.defaultValue.toString());
                    } else {
                        //替换模板中的值
                        template = template.replace(prefix + contractParam.name + suffix, contractParam.value == null ? "" : contractParam.value.toString());
                    }
                    break;
                case TABLE:
                    String table = "";
                    if (contractParam.value == null && contractParam.defaultValue != null) {
                        //生成表格
                        table = genContractTable(contractParam.name, (List) contractParam.defaultValue);
                    } else {
                        if (contractParam.value instanceof List) {
                            //生成表格
                            table = genContractTable(contractParam.name, (List) contractParam.value);
                        }
                    }
                    template = template.replace(prefix + contractParam.name + suffix, table);
                    break;
                default:
                    throw new RuntimeException("参数类型不合法");
            }
        }
        return template;
    }


    public static String genContractTable(String name, List<Object> list) {
        if (list == null || list.isEmpty()) {
            return "";
        }
        StringBuilder table = new StringBuilder();
        table.append("<table class=\"" + name + "\"><thead>");
        String header = genHeader(list.get(0).getClass());
        table.append(header);
        table.append("</thead><tbody>");
        String body = genBody(list);
        table.append(body);
        table.append("</tbody></table>");
        return table.toString();
    }

    //@ExcelProperty
    private static String genHeader(Class<?> clazz) {
        //获取全部@ExcelProperty注解的字段
        List<Field> fieldsListWithAnnotation = AnnotationUtil.getAnnotationsFields(clazz, ApiModelProperty.class);
        StringBuilder header = new StringBuilder();
        header.append("<tr>");
        for (int i = 0; i < fieldsListWithAnnotation.size(); i++) {
            ApiModelProperty excelProperty = fieldsListWithAnnotation.get(i).getAnnotation(ApiModelProperty.class);
            header.append(genTh(0L, (long) i, excelProperty.value()));
        }
        header.append("</tr>");
        return header.toString();
    }

    private static String genBody(List<Object> list) {
        StringBuilder body = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            Object t = list.get(i);
            //获取全部@ExcelProperty注解的字段
            List<Field> fieldsListWithAnnotation = AnnotationUtil.getAnnotationsFields(t.getClass(), ApiModelProperty.class);
            body.append("<tr>");
            for (int j = 0; j < fieldsListWithAnnotation.size(); j++) {
                try {
                    Object value = FieldUtils.readField(fieldsListWithAnnotation.get(j), t, true);
                    //内容是从第二行开始
                    body.append(genTd((long) i + 1, (long) j, value.toString()));
                } catch (IllegalAccessException e) {
                    throw new RuntimeException("获取字段值失败");
                }
            }
            body.append("</tr>");
        }
        return body.toString();
    }

    //th创建
    private static String genTh(Long rowIndex, Long colIndex, String data) {
        return "<th data-id=\"" + rowIndex + "_" + colIndex + "\" >" + data + "</th>";
    }

    //td创建 , 内容的样式不好处理，需要前端根据行和列自行处理  rowIndex+colIndex
    private static String genTd(Long rowIndex, Long colIndex, String data) {
        return "<td data-id=\"" + rowIndex + "_" + colIndex + "\">" + data + "</td>";
    }
}
